/*
 * Copyright (C) 2020  Prasoon Joshi
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package graphql

import generated._
import models.Resolvers
import sangria.schema._
import graphql.SchemaUnions._

object SchemaDefinition {

  implicit val ItemType: ObjectType[Unit, Item] =
    ObjectType(
      "item",
      "An element used in either <list> or as part of <defitem>.",
      () => fields[Unit, Item](
        Field("mixed",
          sangria.schema.ListType(ParaContentableOptionType),
          resolve = {ctx => Resolvers.mParaContentableOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  val Id = Argument("id", IDType, description = "Id of the object.")
  val IdArg = Argument("id", StringType)
  val OffsetArg = Argument("offset", OptionInputType(IntType), 0)
  val LimitArg = Argument("limit", OptionInputType(IntType), 100)

//  def entityFields[T](name: String, tpe: ObjectType[Ctx, T], actor: Ctx ⇒ ActorRef) = fields[Ctx, Unit](
//    Field(name, OptionType(tpe),
//      arguments = IdArg :: Nil,
//      resolve = c ⇒ (actor(c.ctx) ? Get(c.arg(IdArg))).mapTo[Option[T]]),
//    Field(name + "s", ListType(tpe),
//      arguments = OffsetArg :: LimitArg :: Nil,
//      resolve = c ⇒ (actor(c.ctx) ? View.List(c.arg(OffsetArg), c.arg(LimitArg))).mapTo[Seq[T]]))

  val QueryType = ObjectType(
    "query",
    () => fields[GraphQLContext, Unit](
      Field("collection",
        OptionType(EadType),
        description = Some("Finding Aid for a given collection (fonds, record group, manuscript group, etc.)"),
        arguments = Id :: Nil,
        resolve = c => c.ctx.dataRepository.findingAid(c arg Id)),

      Field("allCollections",
        sangria.schema.ListType(EadType),
        description = Some("All finding aid in the archive."),
        resolve = _.ctx.dataRepository.allFindingAid)
    )
  )
//
//  val EadInputType: InputObjectType[E] = In
//  val MutationType = ObjectType(
//    "mutations",
//    () => fields[DataRepository, Unit](
//      Field("collection",
//        EadType,
//        description = Some("Ead3 compliant data"),
//        resolve = c => c.ctx.saveEad(c.)
//    )
//  )
  import sangria.macros.derive._
  import SchemaInputObjects._
  import SchemaInputObjects.EadInputFormat

//  val MutationType = deriveContextObjectType[CtxObject, Mutation, Unit](_.mutation)

  implicit val EadType: ObjectType[Unit, Ead] =
    ObjectType(
      "ead",
      "<ead> wraps all other elements in an Encoded Archival Description document or finding aid. " +
        "Also referred to more specifically as an inventory or register, a finding aid establishes physical and " +
        "intellectual control over many types of archival materials and helps researchers understand and access the " +
        "materials being described. <ead> must contain <control> followed by <archdesc>",
      () => fields[Unit, Ead](
        Field("control", ControlType, resolve = _.value.control),
        Field("archdesc", ArchdescType, resolve = _.value.archdesc),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("relatedencoding", OptionType(StringType), resolve = _.value.relatedencoding),
        Field("base", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.base)})
      )
    )

  implicit val ControlType: ObjectType[Unit, Control] =
    ObjectType(
      "control",
      "A required child element of <ead> for recording bibliographic and administrative information about an EAD instance. ",
      () => fields[Unit, Control](
        Field("recordid", RecordidType, resolve = _.value.recordid),
        Field("otherrecordid", sangria.schema.ListType(OtherrecordidType), resolve = _.value.otherrecordid),
        Field("representation", sangria.schema.ListType(RepresentationType), resolve = _.value.representation),
        Field("filedesc", FiledescType, resolve = _.value.filedesc),
        Field("maintenancestatus", MaintenancestatusType, resolve = _.value.maintenancestatus),
        Field("maintenanceagency", MaintenanceagencyType, resolve = _.value.maintenanceagency),
        Field("languagedeclaration", sangria.schema.ListType(LanguagedeclarationType), resolve = _.value.languagedeclaration),
        Field("conventiondeclaration", sangria.schema.ListType(ConventiondeclarationType), resolve = _.value.conventiondeclaration),
        Field("rightsdeclaration", sangria.schema.ListType(RightsdeclarationType), resolve = _.value.rightsdeclaration),
        Field("localtypedeclaration", sangria.schema.ListType(LocaltypedeclarationType), resolve = _.value.localtypedeclaration),
        Field("localcontrol", sangria.schema.ListType(LocalcontrolType), resolve = _.value.localcontrol),
        Field("maintenancehistory", MaintenancehistoryType, resolve = _.value.maintenancehistory),
        Field("sources", OptionType(SourcesType), resolve = _.value.sources),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relatedencoding", OptionType(StringType), resolve = _.value.relatedencoding),
        Field("base", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("langencoding", OptionType(StringType),
          resolve = {ctx => Resolvers.langencodingResolver(ctx.value.langencoding)}),
        Field("scriptencoding", OptionType(StringType),
          resolve = {ctx => Resolvers.scriptEncodingResolver(ctx.value.scriptencoding)}),
        Field("dateencoding", OptionType(StringType),
          resolve = {ctx => Resolvers.dateEncodingResolver(ctx.value.dateencoding)}),
        Field("countryencoding", OptionType(StringType),
          resolve = {ctx => Resolvers.countryEncodingResolver(ctx.value.countryencoding)}),
        Field("repositoryencoding", OptionType(StringType),
          resolve = {ctx => Resolvers.repositoryEncodingResolver(ctx.value.repositoryencoding)})
      )
    )


  implicit val ArchdescType: ObjectType[Unit, ArchDescription] =
    ObjectType(
      "archdesc",
      "Binds together all the Archival Description information in the EAD instance",
      () => fields[Unit, ArchDescription](
        Field("did", DidType, resolve = _.value.did),
        Field("archdescoption", sangria.schema.ListType(ArchDescOptionType),
            resolve = {ctx => ctx.value.archdescoption.map(p => p.value)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("relatedencoding", OptionType(StringType), resolve = _.value.relatedencoding),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("level", StringType,
          resolve = {ctx => Resolvers.levelTypeResolver(ctx.value.level)}),
        Field("base", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.base)})
      )
    )



  implicit lazy val AccessrestrictType: ObjectType[Unit, Accessrestrict] =
    ObjectType(
      "accessrestrict",
      "An element for information about conditions that affect the availability of the materials being described.",
      () => fields[Unit, Accessrestrict](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("accessrestrictoption", sangria.schema.ListType(AccessRestrictOptionType),
          resolve = {ctx => Resolvers.accessRestrictOptionResolver(ctx.value.accessrestrictoption)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val BlockquoteType: ObjectType[Unit, Blockquote] =
    ObjectType(
      "blockquote",
      "A generic formatting element that designates an extended quotation.",
      () => fields[Unit, Blockquote](
        Field("blockquoteoption", sangria.schema.ListType(BlockQuoteOptionType),
          resolve = {ctx => Resolvers.blockquoteOptionResolver(ctx.value.blockquoteoption)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val ChronlistType: ObjectType[Unit, Chronlist] =
    ObjectType(
      "chronlist",
      "An element for designating the temporal sequence of significant events associated with the entity or material described.",
      () => fields[Unit, Chronlist](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("listhead", OptionType(ListheadType), resolve = _.value.listhead),
        Field("chronitem", sangria.schema.ListType(ChronitemType), resolve = _.value.chronitem),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val ListheadType: ObjectType[Unit, Listhead] =
    ObjectType(
      "listhead",
      "An element for grouping several headings for faceted lists.",
      () => fields[Unit, Listhead](
        Field("head01", OptionType(Head01Type), resolve = _.value.head01),
        Field("head02", OptionType(Head02Type), resolve = _.value.head02),
        Field("head03", OptionType(Head03Type), resolve = _.value.head03),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val Head01Type: ObjectType[Unit, Head01] =
    ObjectType(
      "head01",
      "A formatting element for the first facet heading in a multifacet list.",
      () => fields[Unit, Head01](
        Field("mixed", sangria.schema.ListType(MixedBasicElementsOption1Type),
          resolve = {ctx =>
            Resolvers.mMixedBasicElementsOption1Resolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val Head02Type: ObjectType[Unit, Head02] =
    ObjectType(
      "head02",
      "A formatting element for the second facet heading in a multifacet list.",
      () => fields[Unit, Head02](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val Head03Type: ObjectType[Unit, Head03] =
    ObjectType(
      "head03",
      "A formatting element for the third facet heading in a multifacet list.",
      () => fields[Unit, Head03](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val ChronitemsetType: ObjectType[Unit, Chronitemset] =
    ObjectType(
      "chronitemset",
      "An element for binding together zero or more <geogname> elements and one or more <event> elements within <chronitem>.",
      () => fields[Unit, Chronitemset](
        Field("geogname", sangria.schema.ListType(GeognameType), resolve = _.value.geogname),
        Field("event", sangria.schema.ListType(EventType), resolve = _.value.event),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val DatesetType: ObjectType[Unit, Dateset] =
    ObjectType(
      "dateset",
      "A wrapper element for encoding complex dates that cannot be adequately represented in one <datesingle> or <daterange>.",
      () => fields[Unit, Dateset](
        Field("datesetoption", DatesetOptionType,
          resolve = {ctx => Resolvers.datesetOptionResolver(ctx.value.datesetoption)}),
        Field("datesetoption2", sangria.schema.ListType(DatesetOption2Type),
          resolve = {ctx => Resolvers.datesetOption2Resolver(ctx.value.datesetoption2)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val EventType: ObjectType[Unit, Event] =
    ObjectType(
      "event",
      "An element describing a happening or occurrence recorded within a chronology list.",
      () => fields[Unit, Event](
        Field("mixed",
          sangria.schema.ListType(ParaContentableOptionType),
          resolve = {ctx => Resolvers.mParaContentableOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val ChronitemType: ObjectType[Unit, Chronitem] =
    ObjectType(
      "chronitem",
      "An element that pairs a date with one or more events and zero or more geographic names within a chronology list <chronlist>.",
      () => fields[Unit, Chronitem](
        Field("chronitemoption", ChronItemOptionType,
          resolve = {ctx => Resolvers.chronitemOptionResolver(ctx.value.chronitemoption)}),
        Field("chronitemoption2", sangria.schema.ListType(ChronItemOption2Type),
          resolve = {ctx => Resolvers.chronitemOption2Resolver(ctx.value.chronitemoption2)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val ChronitemSequence1Type: ObjectType[Unit, ChronitemSequence1] =
    ObjectType(
      "chronitemsequence1",
      "geogname: Option[Geogname] = None,\n  event: Event) extends ChronitemOption2",
      () => fields[Unit, ChronitemSequence1](
        Field("geogname", OptionType(GeognameType), resolve = _.value.geogname),
        Field("event", EventType, resolve = _.value.event)
      )
    )

  implicit val ListTypeSequence1Type: ObjectType[Unit, ListTypeSequence1] =
    ObjectType(
      "listtypesequence1",
      "ListTypeSequence",
      () => fields[Unit, ListTypeSequence1](
        Field("listhead", OptionType(ListheadType), resolve = _.value.listhead),
        Field("defitem", sangria.schema.ListType(DefitemType),
          resolve = _.value.defitem)
      )
    )

  implicit val DefitemType: ObjectType[Unit, Defitem] =
    ObjectType(
      "defitem",
      "A wrapper element for binding pairs of labels and items within a list.",
      () => fields[Unit, Defitem](
        Field("label", LabelType, resolve = _.value.label),
        Field("item", ItemType, resolve = _.value.item),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val LabelType: ObjectType[Unit, Label] =
    ObjectType(
      "label",
      "A required child element of <defitem> that identifies the term or concept being defined or described.",
      () => fields[Unit, Label](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val ListTypeType: ObjectType[Unit, generated.ListType] =
    ObjectType(
      "list",
      "A wrapper element for formatting a series of <item> or <defitem> elements that are often presented in a vertical sequence.",
      () => fields[Unit, generated.ListType](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("listtypeoption", sangria.schema.ListType(ListTypeOptionType),
          resolve = {ctx => Resolvers.listTypeOptionTypeResolver(ctx.value.listtypeoption)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("listtype", OptionType(StringType), resolve = _.value.listtype.map(_.toString)),
        Field("mark", OptionType(StringType), resolve = _.value.mark.map(_.toString)),
        Field("numeration", OptionType(StringType), resolve = _.value.numeration.map(_.toString))
      )
    )

  implicit val PType: ObjectType[Unit, P] =
    ObjectType(
      "p",
      "A general purpose element used to encode blocks of text.",
      () => fields[Unit, P](
        Field("mixed",
          sangria.schema.ListType(ParaContentableOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val TableType: ObjectType[Unit, Table] =
    ObjectType(
      "table",
      "A wrapper element for formatting information in a row and column display.",
      () => fields[Unit, Table](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("tgroup", sangria.schema.ListType(TgroupType), resolve = _.value.tgroup),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("frame", OptionType(StringType), resolve = _.value.frame.map(_.toString)),
        Field("colsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.colsep)}),
        Field("rowsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.rowsep)}),
        Field("pgwide", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.pgwide)})
      )
    )

  implicit val TgroupType: ObjectType[Unit, Tgroup] =
    ObjectType(
      "tgroup",
      "A wrapper element that binds together <colspec>, <thead>, and <tbody> elements in a table.",
      () => fields[Unit, Tgroup](
        Field("colspec", sangria.schema.ListType(ColspecType), resolve = _.value.colspec),
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("tbody", TbodyType, resolve = _.value.tbody),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("cols", StringType, resolve = _.value.cols),
        Field("colsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.colsep)}),
        Field("rowsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.rowsep)}),
        Field("align", OptionType(StringType),
          resolve = {ctx => Resolvers.typeToStringResolver[Align](ctx.value.align)})
      )
    )

  implicit val ColspecType: ObjectType[Unit, Colspec] =
    ObjectType(
      "colspec",
      "An empty formatting element that specifies the position and size of a single column in a table.",
      () => fields[Unit, Colspec](
        Field("colnum", OptionType(StringType), resolve = _.value.colnum),
        Field("colname", OptionType(StringType), resolve = _.value.colname),
        Field("colwidth", OptionType(StringType), resolve = _.value.colwidth),
        Field("colsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.colsep)}),
        Field("rowsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.rowsep)}),
        Field("align", OptionType(StringType),
          resolve = {ctx => Resolvers.alignTypeResolver(ctx.value.align)}),
        Field("char", OptionType(StringType), resolve = _.value.char),
        Field("charoff", OptionType(StringType), resolve = _.value.charoff)
      )
    )

  implicit val TheadType: ObjectType[Unit, Thead] =
    ObjectType(
      "thead",
      "A formatting element that contains the heading information in <table>.",
      () => fields[Unit, Thead](
        Field("row", sangria.schema.ListType(RowType), resolve = _.value.row),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("valign", OptionType(StringType),
          resolve = {ctx => Resolvers.valignType3Resolver(ctx.value.valign)})
      )
    )

  implicit val RowType: ObjectType[Unit, Row] =
    ObjectType(
      "row",
      "A formatting element that contains one or more horizontal cells in a table.",
      () => fields[Unit, Row](
        Field("entry", sangria.schema.ListType(EntryType), resolve = _.value.entry),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.typeToStringResolver[Audience](ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("rowsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.rowsep)}),
        Field("valign", OptionType(StringType),
          resolve = {ctx => Resolvers.typeToStringResolver[ValignType](ctx.value.valign)})
      )
    )

  implicit val EntryType: ObjectType[Unit, Entry] =
    ObjectType(
      "entry",
      "A formatting element that designates the contents of a cell in a table.",
      () => fields[Unit, Entry](
        Field("mixed",
          sangria.schema.ListType(ParaContentableOptionType),
          resolve = {ctx => Resolvers.mParaContentableOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.typeToStringResolver[Audience](ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("colname", OptionType(StringType), resolve = _.value.colname),
        Field("namest", OptionType(StringType), resolve = _.value.namest),
        Field("nameend", OptionType(StringType), resolve = _.value.nameend),
        Field("morerows", OptionType(StringType), resolve = _.value.morerows),
        Field("colsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.colsep)}),
        Field("rowsep", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.rowsep)}),
        Field("align", OptionType(StringType),
          resolve = {ctx => Resolvers.typeToStringResolver[AlignType2](ctx.value.align)}),
        Field("char", OptionType(StringType), resolve = _.value.char),
        Field("charoff", OptionType(StringType), resolve = _.value.charoff),
        Field("valign", OptionType(StringType),
          resolve = {ctx => Resolvers.typeToStringResolver[ValignType2](ctx.value.valign)})
      )
    )

//  //TODO: Use currying
//  def mCommonAttributes() = List(Field("id", OptionType(StringType), resolve = _.value.id),
//    Field("altrender", OptionType(StringType), resolve = _.value.altrender),
//    Field("audience", OptionType(StringType),
//      resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
//    Field("lang", OptionType(StringType), resolve = _.value.lang),
//    Field("script", OptionType(StringType), resolve = _.value.script))

  implicit val TbodyType: ObjectType[Unit, Tbody] =
    ObjectType(
      "tbody",
      "A child element of <tgroup> that binds together one or more rows forming the main body of a table.",
      () => fields[Unit, Tbody](
        Field("row", sangria.schema.ListType(RowType), resolve = _.value.row),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("valign", OptionType(StringType),
          resolve = {ctx => Resolvers.typeToStringResolver[Valign](ctx.value.valign)})
      )
    )

  implicit val AccrualsType: ObjectType[Unit, Accruals] =
    ObjectType(
      "accruals",
      "An element for information about anticipated additions to the materials being described.",
      () => fields[Unit, Accruals](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("accrualsoption", sangria.schema.ListType(AccrualsOptionType),
          resolve = _.value.accrualsoption.map(p => p.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val AcqinfoType: ObjectType[Unit, Acqinfo] =
    ObjectType(
      "acqinfo",
      "An element for encoding the immediate source of acquisition of the materials being described.",
      () => fields[Unit, Acqinfo](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("acqinfooption", sangria.schema.ListType(AcqInfoOptionType),
          resolve = _.value.acqinfooption.map(p => p.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val AltformavailType: ObjectType[Unit, Altformavail] =
    ObjectType(
      "altformavail",
      "An element for indicating the existence of copies of the materials being described.",
      () => fields[Unit, Altformavail](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("altformavailoption", sangria.schema.ListType(AltFormAvailOptionType),
          resolve = _.value.altformavailoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val AppraisalType: ObjectType[Unit, Appraisal] =
    ObjectType(
      "appraisal",
      "An element for documenting decisions and actions related to assessing the archival value and " +
        "disposition of the materials being described.",
      () => fields[Unit, Appraisal](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("appraisaloption", sangria.schema.ListType(AppraisalOptionType),
          resolve = _.value.appraisaloption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit lazy val ArrangementType: ObjectType[Unit, Arrangement] =
    ObjectType(
      "arrangement",
      "An element for describing the organization or filing sequence of the records.",
      () => fields[Unit, Arrangement](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("arrangementoption", sangria.schema.ListType(ArrangementOptionType),
          resolve = _.value.arrangementoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val BibrefType: ObjectType[Unit, Bibref] =
    ObjectType(
      "bibref",
      "An element for citing a published work.",
      () => fields[Unit, Bibref](
        Field("mixed",
          sangria.schema.ListType(MixedBasicPlusAccessibleOptionType),
          resolve = _.value.mixed),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  case class FreeText(text: String)

  implicit val FreeTextType: ObjectType[Unit, FreeText] =
    ObjectType(
      "text",
      "Free text inside a mixed field",
      () => fields[Unit, FreeText](
        Field("text", StringType, resolve = _.value.text)
      )
    )

  implicit val ArchrefType: ObjectType[Unit, Archref] =
    ObjectType(
      "archref",
      "An element for citing other archival materials.",
      () => fields[Unit, Archref](
        Field("mixed",
          sangria.schema.ListType(MixedBasicPlusAccessibleOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val BibliographyType: ObjectType[Unit, Bibliography] =
    ObjectType(
      "bibliography",
      "For citing works based on the use or analysis of the materials being described.",
      () => fields[Unit, Bibliography](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("bibliographyoption", sangria.schema.ListType(BibliographyOptionType),
          resolve = _.value.bibliographyoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val BioghistType: ObjectType[Unit, Bioghist] =
    ObjectType(
      "bioghist",
      "For recording biographical or historical information about the creator(s) of the materials being described.",
      () => fields[Unit, Bioghist](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("bioghistoption", sangria.schema.ListType(BiogHistOptionType),
          resolve = _.value.bioghistoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val ControlaccessType: ObjectType[Unit, Controlaccess] =
    ObjectType(
      "controlaccess",
      "An element that binds together elements containing access headings for the described materials. ",
      () => fields[Unit, Controlaccess](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("controlaccessoption", sangria.schema.ListType(ControlAccessOptionType),
          resolve = _.value.controlaccessoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val CustodhistType: ObjectType[Unit, Custodhist] =
    ObjectType(
      "custodhist",
      "An element for information about the chain of ownership or custody of the materials being described, " +
        "before they reached the archives.",
      () => fields[Unit, Custodhist](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("custodhistoption", sangria.schema.ListType(CustodHistOptionType),
          resolve = _.value.custodhistoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val FileplanType: ObjectType[Unit, Fileplan] =
    ObjectType(
      "fileplan",
      "An element for information about any classification scheme used by the original creator to arrange, " +
        "store, and retrieve the materials described.",
      () => fields[Unit, Fileplan](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("fileplanoption", sangria.schema.ListType(FilePlanOptionType),
          resolve = _.value.fileplanoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val NamegrpType: ObjectType[Unit, Namegrp] =
    ObjectType(
      "namegrp",
      "An element for binding together multiple access element entries within an <indexentry>.",
      () => fields[Unit, Namegrp](
        Field("accessoptions", sangria.schema.ListType(AccessType),
          resolve = _.value.mu46accessOption1.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val PtrgrpType: ObjectType[Unit, Ptrgrp] =
    ObjectType(
      "ptrgrp",
      "An element for binding together two or more <ptr> or <ref> elements.",
      () => fields[Unit, Ptrgrp](
        Field("referenceoptions", sangria.schema.ListType(RefsOptionsType),
          resolve = _.value.mu46refsOption1.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val IndexentryType: ObjectType[Unit, Indexentry] =
    ObjectType(
      "indexentry",
      "A wrapper element that pairs an index term with zero or more linking elements.",
      () => fields[Unit, Indexentry](
        Field("indexentryoption", IndexEntryOptionType,
          resolve = _.value.indexentryoption),
        Field("indexentryoption2", OptionType(IndexEntryOption2Type),
          resolve = _.value.indexentryoption2.map(_.value)),
        Field("indexentry", sangria.schema.ListType(IndexentryType),
          resolve = _.value.indexentry),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val IndexType: ObjectType[Unit, Index] =
    ObjectType(
      "index",
      "A list of key terms and entities with reference pointers assembled to enhance navigation of and access " +
        "to the materials being described.",
      () => fields[Unit, Index](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("blocksOptions", sangria.schema.ListType(BlocksOptionType),
          resolve = _.value.mu46blocksOption2.map(_.value)),
        Field("indexoption", sangria.schema.ListType(IndexOptionType),
          resolve = _.value.indexoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val LegalstatusType: ObjectType[Unit, Legalstatus] =
    ObjectType(
      "legalstatus",
      "An element for indicating the statutorily defined status of the materials being described.",
      () => fields[Unit, Legalstatus](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("legalstatusoption", sangria.schema.ListType(LegalStatusOptionType),
          resolve = _.value.legalstatusoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val OddType: ObjectType[Unit, Odd] =
    ObjectType(
      "odd",
      "For recording additional information about the described materials that is not easily incorporated into one of " +
        "the other named elements within <archdesc> and <c>. ",
      () => fields[Unit, Odd](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("oddoption", sangria.schema.ListType(OddOptionType),
          resolve = _.value.oddoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val OriginalslocType: ObjectType[Unit, Originalsloc] =
    ObjectType(
      "originalsloc",
      "For conveying information about the existence of originals when the unit described exists of copies.",
      () => fields[Unit, Originalsloc](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("originalslocoption", sangria.schema.ListType(OriginalsLocOptionType),
          resolve = _.value.originalslocoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val OtherfindaidType: ObjectType[Unit, Otherfindaid] =
    ObjectType(
      "otherfindaid",
      "For identifying any other finding aids to the materials being described.",
      () => fields[Unit, Otherfindaid](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("otherfindaidoption", sangria.schema.ListType(OtherFindAidOptionType),
          resolve = _.value.otherfindaidoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val PhystechType: ObjectType[Unit, Phystech] =
    ObjectType(
      "phystech",
      "For describing the physical condition of the materials and/or technical requirements that affect their use. ",
      () => fields[Unit, Phystech](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("phystechoption", sangria.schema.ListType(PhysTechOptionType),
          resolve = _.value.phystechoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
      )
    )

  implicit val PreferciteType: ObjectType[Unit, Prefercite] =
    ObjectType(
      "prefercite",
      "An element for specifying how users should cite the described materials in publication credits.",
      () => fields[Unit, Prefercite](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("preferciteoption", sangria.schema.ListType(PrefereCiteOptionType),
          resolve = _.value.preferciteoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val ProcessinfoType: ObjectType[Unit, Processinfo] =
    ObjectType(
      "processinfo",
      "For encoding information about archival activities related to the described materials.",
      () => fields[Unit, Processinfo](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("processinfooption", sangria.schema.ListType(ProcessInfoOptionType),
          resolve = _.value.processinfooption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val RelatedmaterialType: ObjectType[Unit, Relatedmaterial] =
    ObjectType(
      "relatedmaterial",
      "For identifying archival materials that have an association to the materials being described.",
      () => fields[Unit, Relatedmaterial](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("relatedmaterialoption", sangria.schema.ListType(RelatedMaterialOptionType),
          resolve = _.value.relatedmaterialoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  /**
    * A wrapper element that groups together one or more <relation> elements, each of which encodes a specific relationship.
    * The material described in an EAD instance may have relationships with other resources:
    * For archival collections, bibliographic resources, or artifacts, use <relation> with the @relationtype set to "resourcerelation."
    *
    * For corporate bodies, persons or families, use <relation> with the @relationtype set to "cpfrelation."
    *
    * For functions use, <relation> with the @relationtype set to "functionrelation."
    *
    * For relationships to other entities such as places, events and topics, use <relation> with the @relationtype set
    * to "otherrelationtype" and the type of related entity specified in the @otherrelationtype.
    */
  implicit val RelationsType: ObjectType[Unit, Relations] =
    ObjectType(
      "relations",
      "An element that groups one or more <relation> elements, which identify external entities and characterize " +
        "the nature of their relationships to the materials being described. ",
      () => fields[Unit, Relations](
        Field("relation", sangria.schema.ListType(RelationType), resolve = _.value.relation),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("base", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.base)})
      )
    )

  implicit val RelationType: ObjectType[Unit, Relation] =
    ObjectType(
      "relation",
      "A child element of <relations> for describing a relationship between the materials described in the " +
        "EAD instance and a related entity.",
      () => fields[Unit, Relation](
        Field("relationentry", sangria.schema.ListType(RelationentryType),
          resolve = _.value.relationentry),
        Field("objectxmlwrap", OptionType(ObjectXmlWrapType), resolve = _.value.objectxmlwrap),
        Field("relationoption", OptionType(RelationOptionType),
          resolve = _.value.relationoption.map(_.value)),
        Field("geogname", OptionType(GeognameType), resolve = _.value.geogname),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relationtype", StringType, resolve = _.value.relationtype.toString),
        Field("otherrelationtype", OptionType(StringType), resolve = _.value.otherrelationtype),
        Field("lastdatetimeverified", OptionType(StringType), resolve = _.value.lastdatetimeverified),
        Field("href", OptionType(StringType), resolve = _.value.href),
        Field("linkrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.linkrole)}),
        Field("arcrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.arcrole)}),
        Field("linktitle", OptionType(StringType), resolve = _.value.linktitle),
        Field("show", OptionType(StringType), resolve = _.value.show.map(p => p.toString)),
        Field("actuate", OptionType(StringType), resolve = _.value.actuate.map(_.toString))
      )
    )

  implicit val RelationentryType: ObjectType[Unit, Relationentry] =
    ObjectType(
      "relationentry",
      "A child element of <relation> that identifies an entity related to the materials being described.",
      () => fields[Unit, Relationentry](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("transliteration", OptionType(StringType), resolve = _.value.transliteration)
      )
    )

  implicit val ScopecontentType: ObjectType[Unit, Scopecontent] =
    ObjectType(
      "scopecontent",
      "An element that provides information about the nature of and activities reflected in the described materials.",
      () => fields[Unit, Scopecontent](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("scopecontentoption", sangria.schema.ListType(ScopeContentOptionType),
          resolve = _.value.scopecontentoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val SeparatedmaterialType: ObjectType[Unit, Separatedmaterial] =
    ObjectType(
      "separatedmaterial",
      "For identifying materials associated by provenance that have been physically separated or removed.",
      () => fields[Unit, Separatedmaterial](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("separatedmaterialoption", sangria.schema.ListType(SeparatedMaterialOptionType),
          resolve = _.value.separatedmaterialoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val UserestrictType: ObjectType[Unit, Userestrict] =
    ObjectType(
      "userestrict",
      "An element for indicating any conditions that affect the use of the described materials, such as in publications.",
      () => fields[Unit, Userestrict](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("userestrictoption", sangria.schema.ListType(UseRestrictOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.userestrictoption)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val DidType: ObjectType[Unit, Did] =
    ObjectType(
      "did",
      "A wrapper element that encloses information essential for identifying the material being described. ",
      () => fields[Unit, Did](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("didOptions", sangria.schema.ListType(DidOptionType),
          resolve = {ctx => ctx.value.mu46didOption2.map(p => p.value)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val AbstractType: ObjectType[Unit, Abstract] =
    ObjectType(
      "abstract",
      "A child element of <did> that provides a brief characterization of the materials being described.",
      () => fields[Unit, Abstract](
        Field("mixed",
          sangria.schema.ListType(MixedBasicPlusAccessibleOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val ContainerType: ObjectType[Unit, Container] =
    ObjectType(
      "container",
      "A child element of <did> for indicating the container in which the material being described is housed, " +
        "e.g., box, folder.",
      () => fields[Unit, Container](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("parent", OptionType(sangria.schema.ListType(StringType)), resolve = _.value.parent),
        Field("containerid", OptionType(StringType), resolve = _.value.containerid)
      )
    )

  implicit val DaoType: ObjectType[Unit, Dao] =
    ObjectType(
      "dao",
      "A child element of <did> used for linking to born digital records or a digital representation of " +
        "the materials being described.",
      () => fields[Unit, Dao](
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.attributes.get("id").map(_.value.asInstanceOf[String])),
        Field("altrender", OptionType(StringType),
          resolve = _.value.attributes.get("altrender").map(_.value.asInstanceOf[String])),
        Field("audience", OptionType(StringType),
          resolve = _.value.attributes.get("audience").map(_.value.asInstanceOf[String])),
        Field("lang", OptionType(StringType),
          resolve = _.value.attributes.get("lang").map(_.value.asInstanceOf[String])),
        Field("script", OptionType(StringType),
          resolve = _.value.attributes.get("script").map(_.value.asInstanceOf[String])),
        Field("encodinganalog", OptionType(StringType),
          resolve = _.value.attributes.get("encodinganalog").map(_.value.asInstanceOf[String])),
        Field("localtype", OptionType(StringType),
          resolve = _.value.attributes.get("localtype").map(_.value.asInstanceOf[String])),
        Field("label", OptionType(StringType),
          resolve = _.value.attributes.get("label").map(_.value.asInstanceOf[String])),
        Field("href", OptionType(StringType),
          resolve = _.value.attributes.get("href").map(_.value.asInstanceOf[String])),
        Field("linkrole", OptionType(StringType),
          resolve = _.value.attributes.get("linkrole").map(_.value.asInstanceOf[String])),
        Field("arcrole", OptionType(StringType),
          resolve = _.value.attributes.get("arcrole").map(_.value.asInstanceOf[String])),
        Field("linktitle", OptionType(StringType),
          resolve = _.value.attributes.get("linktitle").map(_.value.asInstanceOf[String])),
        Field("show", OptionType(StringType),
          resolve = _.value.attributes.get("show").map(_.value.asInstanceOf[String])),
        Field("actuate", OptionType(StringType),
          resolve = _.value.attributes.get("actuate").map(_.value.asInstanceOf[String])),
        Field("identifier", OptionType(StringType),
          resolve = _.value.attributes.get("identifier").map(_.value.asInstanceOf[String])),
        Field("xpointer", OptionType(StringType),
          resolve = _.value.attributes.get("xpointer").map(_.value.asInstanceOf[String])),
        Field("entityref", OptionType(StringType),
          resolve = _.value.attributes.get("entityref").map(_.value.asInstanceOf[String])),
        Field("daotype", OptionType(StringType),
          resolve = _.value.attributes.get("daotype").map(_.value.asInstanceOf[String])),
        Field("otherdaotype", OptionType(StringType),
          resolve = _.value.attributes.get("otherdaotype").map(_.value.asInstanceOf[String])),
        Field("coverage", OptionType(StringType),
          resolve = _.value.attributes.get("coverage").map(_.value.asInstanceOf[String]))
      )
    )

  implicit val DaosetType: ObjectType[Unit, Daoset] =
    ObjectType(
      "daoset",
      "An element for binding together two or more links to digital archival objects.",
      () => fields[Unit, Daoset](
        Field("daoFirst", DaoType, resolve = _.value.daoFirst),
        Field("daoOthers", sangria.schema.ListType(DaoType), resolve = _.value.daoOthers),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("coverage", OptionType(StringType), resolve = _.value.coverage.map(_.toString)),
        Field("base", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.base)})
      )
    )

  implicit val DidnoteType: ObjectType[Unit, Didnote] =
    ObjectType(
      "didnote",
      "A child element of <did> that can express any kind of explanatory information.",
      () => fields[Unit, Didnote](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val LangmaterialType: ObjectType[Unit, Langmaterial] =
    ObjectType(
      "langmaterial",
      "A child element of <did> that identifies languages represented in the materials described.",
      () => fields[Unit, Langmaterial](
        Field("langmaterialoption", sangria.schema.ListType(LangMaterialOptionType),
          resolve = _.value.langmaterialoption.map(_.value)),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val LanguagesetType: ObjectType[Unit, Languageset] =
    ObjectType(
      "languageset",
      "Within <did>, <languageset> is a child element of <langmaterial> that is used to pair languages with the " +
        "scripts in which they are written.",
      () => fields[Unit, Languageset](
        Field("language", sangria.schema.ListType(LanguageType), resolve = _.value.language),
        Field("scriptElement", sangria.schema.ListType(ScriptType), resolve = _.value.scriptElement),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val MaterialspecType: ObjectType[Unit, Materialspec] =
    ObjectType(
      "materialspec",
      "A child elementof <did> for providing material specific details for a small group of materials or an item.",
      () => fields[Unit, Materialspec](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val OriginationType: ObjectType[Unit, Origination] =
    ObjectType(
      "origination",
      "A child element of <did> that names the creator or collector of the described materials.",
      () => fields[Unit, Origination](
        Field("originationoption", sangria.schema.ListType(OriginationOptionType),
          resolve = _.value.originationoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val PhysdescsetType: ObjectType[Unit, Physdescset] =
    ObjectType(
      "physdescset",
      "A child element of <did> used to bind two or more structured expressions of the physical description " +
        "of the materials.",
      () => fields[Unit, Physdescset](
        Field("physdescstructuredFirst", PhysdescstructuredType, resolve = _.value.physdescstructuredFirst),
        Field("physdescstructuredOthers", sangria.schema.ListType(PhysdescstructuredType),
          resolve = _.value.physdescstructuredOthers),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("parallel", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.parallel)}),
        Field("coverage", OptionType(StringType),
          resolve = _.value.coverage.map(_.toString))
      )
    )

  implicit val PhysdescType: ObjectType[Unit, Physdesc] =
    ObjectType(
      "physdesc",
      "A child element of <did> that provides a simple, unstructured statement about the physical characteristics " +
        "of the material being described.",
      () => fields[Unit, Physdesc](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val PhysdescstructuredType: ObjectType[Unit, Physdescstructured] =
    ObjectType(
      "physdescstructured",
      "An element that provides a method for expressing structured statements about the extent and physical " +
        "characteristics of the materials being described.",
      () => fields[Unit, Physdescstructured](
        Field("quantity", QuantityType, resolve = _.value.quantity),
        Field("unittype", UnittypeType, resolve = _.value.unittype),
        Field("physdescstructuredoption", sangria.schema.ListType(PhysDescStructuredOptionType),
          resolve = _.value.physdescstructuredoption.map(_.value)),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("physdescstructuredtype", StringType, resolve = _.value.physdescstructuredtype.toString),
        Field("otherphysdescstructuredtype", OptionType(StringType), resolve = _.value.otherphysdescstructuredtype),
        Field("coverage", StringType, resolve = _.value.coverage.toString)
      )
    )

  implicit val QuantityType: ObjectType[Unit, Quantity] =
    ObjectType(
      "quantity",
      "A required child element of <physdescstructured> that indicates the number of units present as described " +
        "by <unittype>.",
      () => fields[Unit, Quantity](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("approximate", OptionType(BooleanType),
          resolve = {ctx => Resolvers.avBooleanResolver(ctx.value.approximate)})
      )
    )

  implicit val UnittypeType: ObjectType[Unit, Unittype] =
    ObjectType(
      "unittype",
      "A child element of <physdescstructured> that indicates the type of unit being quantified, e.g., boxes, " +
        "linear feet, etc.",
      () => fields[Unit, Unittype](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier)
      )
    )

  implicit val PhyslocType: ObjectType[Unit, Physloc] =
    ObjectType(
      "physloc",
      "A child element of <did> that specifies the physical location of the materials.",
      () => fields[Unit, Physloc](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("parent", OptionType(sangria.schema.ListType(StringType)), resolve = _.value.parent)
      )
    )

  implicit val RepositoryType: ObjectType[Unit, Repository] =
    ObjectType(
      "repository",
      "A child element of <did> that names the institution, person, or family responsible for providing intellectual " +
        "access to the materials being described.",
      () => fields[Unit, Repository](
        Field("repositoryoption", sangria.schema.ListType(RepositoryOptionType),
          resolve = _.value.repositoryoption.map(_.value)),
        Field("address", OptionType(AddressType), resolve = _.value.address),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val UnitdateType: ObjectType[Unit, Unitdate] =
    ObjectType(
      "unitdate",
      "A child element of <did> that provides a simple statement of the date(s) covered by the described materials.",
      () => fields[Unit, Unitdate](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("unitdatetype", OptionType(StringType), resolve = _.value.unitdatetype.map(_.toString)),
        Field("datechar", OptionType(StringType), resolve = _.value.datechar),
        Field("certainty", OptionType(StringType), resolve = _.value.certainty),
        Field("era", OptionType(StringType), resolve = _.value.era),
        Field("calendar", OptionType(StringType), resolve = _.value.calendar),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val UnitdatestructuredType: ObjectType[Unit, Unitdatestructured] =
    ObjectType(
      "unitdatestructured",
      "A child element of <did> that enables structured, machine-processable expressions of the dates of " +
        "the materials being described.",
      () => fields[Unit, Unitdatestructured](
        Field("unitdatestructuredoption", UnitDateStructuredOptionType, resolve = _.value.unitdatestructuredoption),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("unitdatetype", OptionType(StringType), resolve = _.value.unitdatetype.map(_.toString)),
        Field("datechar", OptionType(StringType), resolve = _.value.datechar),
        Field("certainty", OptionType(StringType), resolve = _.value.certainty),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("era", OptionType(StringType), resolve = _.value.era),
        Field("calendar", OptionType(StringType), resolve = _.value.calendar),
      )
    )

  implicit val UnitidType: ObjectType[Unit, Unitid] =
    ObjectType(
      "unitid",
      "A child element of <did> that provides an identifier for the materials being described, such as " +
        "an accession number.",
      () => fields[Unit, Unitid](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("label", OptionType(StringType), resolve = _.value.label),
        //TODO: Restrict to ISO list. Use scala ISO library
        Field("countrycode", OptionType(StringType), resolve = _.value.countrycode),
        Field("repositorycode", OptionType(StringType), resolve = _.value.repositorycode),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val UnittitleType: ObjectType[Unit, Unittitle] =
    ObjectType(
      "unittitle",
      "A child element of <did> that specifies a title for the described materials.",
      () => fields[Unit, Unittitle](
        Field("mixed",
          sangria.schema.ListType(MixedBasicPlusAccessibleOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("normal", OptionType(StringType), resolve = _.value.normal)
      )
    )

  implicit val PhysfacetType: ObjectType[Unit, Physfacet] =
    ObjectType(
      "physfacet",
      "A child element of <physdescstructured> that provides more detailed information about the physical nature of " +
        "or techniques and methods of creation of the material described in terms that are often taken from a " +
        "controlled vocabulary list.",
      () => fields[Unit, Physfacet](
        Field("mixed",
          sangria.schema.ListType(MixedBasicPlusAccessibleOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val DimensionsType: ObjectType[Unit, Dimensions] =
    ObjectType(
      "dimensions",
      "A child element of <physdescstructured> that provides information about the size of the material being described.",
      () => fields[Unit, Dimensions](
        Field("mixed", sangria.schema.ListType(DimensionsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("unit", OptionType(StringType), resolve = _.value.unit)
      )
    )


  implicit val HeadType: ObjectType[Unit, Head] =
    ObjectType(
      "head",
      "An element that encodes a title or caption for a section of text.",
      () => fields[Unit, Head](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mixedElementsResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("althead", OptionType(StringType), resolve = _.value.althead)
      )
    )

  implicit val AbbrType: ObjectType[Unit, Abbr] =
    ObjectType(
      "abbr",
      "An element for encoding the shortened form of a word or phrase.",
      () => fields[Unit, Abbr](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("expan", OptionType(StringType), resolve = _.value.expan)
      )
    )

  implicit val EmphType: ObjectType[Unit, Emph] =
    ObjectType(
      "emph",
      "A formatting element for marking words or phrases that are emphasized or specially formatted.",
      () => fields[Unit, Emph](
        Field("mixed", sangria.schema.ListType(MixedBasicElementsOption1Type),
          resolve = {ctx =>
            Resolvers.mMixedBasicElementsOption1Resolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("render", OptionType(StringType),
          resolve = {ctx => Resolvers.renderType2Resolver(ctx.value.render)})
      )
    )

  implicit val ExpanType: ObjectType[Unit, Expan] =
    ObjectType(
      "expan",
      "A phrase level element for designating the full form of a word or phrase.",
      () => fields[Unit, Expan](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("abbr", OptionType(StringType), resolve = _.value.abbr)
      )
    )

  implicit val ForeignType: ObjectType[Unit, Foreign] =
    ObjectType(
      "foreign",
      "An element that indicates that the language and/or script of the encoded word(s) is different from that in the " +
        "surrounding text.",
      () => fields[Unit, Foreign](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("render", OptionType(StringType),
          resolve = {ctx => Resolvers.renderType3Resolver(ctx.value.render)})
      )
    )

  implicit val LbType: ObjectType[Unit, Lb] =
    ObjectType(
      "lb",
      "A formatting element that forces the following text to start on a new line.",
      fields[Unit, Lb](
        Field("dummyfield", OptionType(StringType), resolve = _.value.toString)
      )
    )

  implicit val PtrType: ObjectType[Unit, Ptr] =
    ObjectType(
      "ptr",
      "An empty element that provides links to content that may be internal or external to the finding aid.",
      fields[Unit, Ptr](
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("target", OptionType(StringType), resolve = _.value.target),
        Field("xpointer", OptionType(StringType), resolve = _.value.xpointer),
        Field("href", OptionType(StringType), resolve = _.value.href),
        Field("linkrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.linkrole)}),
        Field("arcrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.arcrole)}),
        Field("linktitle", OptionType(StringType), resolve = _.value.linktitle),
        Field("show", OptionType(StringType),
          resolve = {ctx => Resolvers.showTypeResolver(ctx.value.show)}),
        Field("actuate", OptionType(StringType),
          resolve = {ctx => Resolvers.actuateTypeResolver(ctx.value.actuate)}),
        Field("entityref", OptionType(StringType), resolve = _.value.entityref)
      )
    )

  implicit val RefType: ObjectType[Unit, Ref] =
    ObjectType(
      "ref",
      "An element that provides a link to content that may be internal or external to the finding aid.",
      () => fields[Unit, Ref](
        Field("mixed", sangria.schema.ListType(RefOptionType),
          resolve = {ctx => Resolvers.mRefOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("target", OptionType(StringType), resolve = _.value.target),
        Field("xpointer", OptionType(StringType), resolve = _.value.xpointer),
        Field("href", OptionType(StringType), resolve = _.value.href),
        Field("linkrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.linkrole)}),
        Field("arcrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.arcrole)}),
        Field("linktitle", OptionType(StringType), resolve = _.value.linktitle),
        Field("show", OptionType(StringType),
          resolve = {ctx => Resolvers.showTypeResolver(ctx.value.show)}),
        Field("actuate", OptionType(StringType),
          resolve = {ctx => Resolvers.actuateTypeResolver(ctx.value.actuate)}),
        Field("entityref", OptionType(StringType), resolve = _.value.entityref)
      )
    )

  implicit val TitleType: ObjectType[Unit, Title] =
    ObjectType(
      "title",
      "An element for encoding the formal name of a work.",
      () => fields[Unit, Title](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relator", OptionType(StringType), resolve = _.value.relator),
        Field("render", OptionType(StringType),
          resolve = {ctx => Resolvers.renderTypeResolver(ctx.value.render)})
      )
    )

  implicit val SubjectType: ObjectType[Unit, Subject] =
    ObjectType(
      "subject",
      "An element for encoding topics represented in the materials being described.",
      () => fields[Unit, Subject](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val PersnameType: ObjectType[Unit, Persname] =
    ObjectType(
      "persname",
      "An element for identifying a personal name.",
      () => fields[Unit, Persname](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val OccupationType: ObjectType[Unit, Occupation] =
    ObjectType(
      "occupation",
      "An element for specifying a profession.",
      () => fields[Unit, Occupation](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val QuoteType: ObjectType[Unit, Quote] =
    ObjectType(
      "quote",
      "A phrase-level element for identifying or formatting an inline quotation.",
      () => fields[Unit, Quote](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOption1Type),
          resolve = {ctx => Resolvers.mMixedBasicElementsOption1Resolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("render", OptionType(StringType),
          resolve = {ctx => Resolvers.renderType4Resolver(ctx.value.render)})
      )
    )

  implicit val NumType: ObjectType[Unit, Num] =
    ObjectType(
      "num",
      "A generic element for expressing numeric information.",
      () => fields[Unit, Num](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val NameType: ObjectType[Unit, Name] =
    ObjectType(
      "name",
      "An element for encoding generic names.",
      () => fields[Unit, Name](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val GeognameType: ObjectType[Unit, Geogname] =
    ObjectType(
      "geogname",
      "An element for encoding place names.",
      () => fields[Unit, Geogname](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("geographiccoordinates",
          sangria.schema.ListType(GeographiccoordinatesType),
          resolve = _.value.geographiccoordinates),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val GeographiccoordinatesType: ObjectType[Unit, Geographiccoordinates] =
    ObjectType(
      "geographiccoordinates",
      "A child element of <geogname> that encodes a set of geographic coordinates.",
      () => fields[Unit, Geographiccoordinates](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("coordinatesystem", StringType, resolve = _.value.coordinatesystem)
      )
    )

  implicit val GenreformType: ObjectType[Unit, Genreform] =
    ObjectType(
      "genreform",
      "An element for encoding a genre or form of material.",
      () => fields[Unit, Genreform](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val FunctionTypeType: ObjectType[Unit, FunctionType] =
    ObjectType(
      "functiontype",
      "An element for encoding activities and processes related to the production of materials.",
      () => fields[Unit, FunctionType](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val FootnoteType: ObjectType[Unit, Footnote] =
    ObjectType(
      "footnote",
      "An element used to cite the source of a fact, quotation, etc.",
      () => fields[Unit, Footnote](
        Field("blocksOptions",
          sangria.schema.ListType(BlocksOptionType),
          resolve = {ctx => Resolvers.mBlocksOptionResolver(ctx.value.mu46blocksOption1)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("show", OptionType(StringType),
          resolve = {ctx => Resolvers.showResolver(ctx.value.show)}),
        Field("actuate", OptionType(StringType),
          resolve = {ctx => Resolvers.actuateResolver(ctx.value.actuate)})
      )
    )

  implicit val FamnameType: ObjectType[Unit, Famname] =
    ObjectType(
      "famname",
      "An element for identifying the name of a group of people with blood relations, or persons who form a household.",
      () => fields[Unit, Famname](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val DateType: ObjectType[Unit, Date] =
    ObjectType(
      "date",
      "An element used to express a date.",
      () => fields[Unit, Date](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("era", OptionType(StringType), resolve = _.value.era),
        Field("calendar", OptionType(StringType), resolve = _.value.calendar),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("certainty", OptionType(StringType), resolve = _.value.certainty),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val CorpnameType: ObjectType[Unit, Corpname] =
    ObjectType(
      "corpname",
      "An element for identifying the name of an organization or group of people.",
      () => fields[Unit, Corpname](
        Field("part", sangria.schema.ListType(PartType), resolve = _.value.part),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier),
        Field("normal", OptionType(StringType), resolve = _.value.normal),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("relator", OptionType(StringType), resolve = _.value.relator)
      )
    )

  implicit val PartType: ObjectType[Unit, Part] =
    ObjectType(
      "part",
      "A required and repeatable child of controlled access elements used to encode one or more parts of an access term.",
      () => fields[Unit, Part](
        Field("mixed",
          sangria.schema.ListType(MixedBasicDateElementsOption1Type),
          resolve = {ctx => Resolvers.mMixedBasicDateElementsOption1Resolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier)
      )
    )

  implicit val RecordidType: ObjectType[Unit, Recordid] =
    ObjectType(
      "recordid",
      "Unique identifier for the EAD instance",
      fields[Unit, Recordid](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("instanceurl", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.instanceurl)})
      )
    )

  lazy implicit val OtherrecordidType: ObjectType[Unit, Otherrecordid] =
    ObjectType(
      "otherrecordid",
      "A child element of <control> that encodes any local identifier for the EAD instance. ",
      () => fields[Unit, Otherrecordid](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val RepresentationType: ObjectType[Unit, Representation] =
    ObjectType(
      "respresentation",
      "The EAD is available at this link as a PDF, XML, HTML, etc.",
      fields[Unit, Representation](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("href", OptionType(StringType), resolve = _.value.href),
        Field("linkrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.linkrole)}),
        Field("arcrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.arcrole)}),
        Field("linktitle", OptionType(StringType), resolve = _.value.linktitle),
        Field("show", OptionType(StringType),
          resolve = {ctx => Resolvers.showTypeResolver(ctx.value.show)}),
        Field("actuate", OptionType(StringType),
          resolve = {ctx => Resolvers.actuateTypeResolver(ctx.value.actuate)}),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val FiledescType: ObjectType[Unit, Filedesc] =
    ObjectType(
      "filedesc",
      "Use <filedesc> to record a bibliographic description of the finding aid itself, including its author, title, " +
        "subtitle, sponsor, edition, publisher, publishing series, and related notes",
      () => fields[Unit, Filedesc](
        Field("titlestmt", TitlestmtType, resolve = _.value.titlestmt),
        Field("editionstmt", OptionType(EditionstmtType), resolve = _.value.editionstmt),
        Field("publicationstmt", OptionType(PublicationstmtType), resolve = _.value.publicationstmt),
        Field("seriesstmt", OptionType(SeriesstmtType), resolve = _.value.seriesstmt),
        Field("notestmt", OptionType(NotestmtType), resolve = _.value.notestmt),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit lazy val SeriesstmtType: ObjectType[Unit, Seriesstmt] =
    ObjectType(
      "seriesstmt",
      "A child element of <filedesc> that groups information about the published monographic series to which an " +
        "EAD instance belongs.",
      () => fields[Unit, Seriesstmt](
        Field("seriesstmtoption",
          sangria.schema.ListType(SeriesStmtOptionType),
          resolve = {ctx => Resolvers.seriesstmtOptionResolver(ctx.value.seriesstmtoption)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val NotestmtType: ObjectType[Unit, Notestmt] =
    ObjectType(
      "notestmt",
      "An optional child element of <filedesc> that binds together one or more <controlnote> elements.",
      () => fields[Unit, Notestmt](
        Field("controlnote", sangria.schema.ListType(ControlnoteType), resolve = _.value.controlnote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val ControlnoteType: ObjectType[Unit, Controlnote] =
    ObjectType(
      "controlnote",
      "A child element of <notestmt>, used to provide a general note related to the EAD instance.",
      () => fields[Unit, Controlnote](
        Field("blocksOptions",
          sangria.schema.ListType(BlocksOptionType),
          resolve = {ctx => Resolvers.mBlocksOptionResolver(ctx.value.mu46blocksOption1)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val TitlestmtType: ObjectType[Unit, Titlestmt] =
    ObjectType(
      "titlestmt",
      "A required child element of <filedesc> that binds together information about the name of an encoded " +
        "finding aid and those responsible for its content.",
      () => fields[Unit, Titlestmt](
        Field("titleproper", sangria.schema.ListType(TitleproperType), resolve = _.value.titleproper),
        Field("subtitle", sangria.schema.ListType(SubtitleType), resolve = _.value.subtitle),
        Field("author", sangria.schema.ListType(AuthorType), resolve = _.value.author),
        Field("sponsor", sangria.schema.ListType(SponsorType), resolve = _.value.sponsor),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val TitleproperType: ObjectType[Unit, Titleproper] =
    ObjectType(
      "titleproper",
      "A child element of <titlestmt> and <seriesstmt> that indicates the title of a finding aid or finding aid series.",
      () => fields[Unit, Titleproper](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("render", OptionType(StringType),
          resolve = {ctx => Resolvers.renderResolver(ctx.value.render)}),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val SubtitleType: ObjectType[Unit, Subtitle] =
    ObjectType(
      "subtitle",
      "A child element of <titlestmt> that captures a secondary or subsidiary portion of the title of the EAD instance.",
      () => fields[Unit, Subtitle](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val AuthorType: ObjectType[Unit, Author] =
    ObjectType(
      "author",
      "An optional child element of <titlestmt> that provides the name(s) of the institution(s) or individual(s) " +
        "responsible for compiling the intellectual content of the EAD instance. ",
      () => fields[Unit, Author](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val SponsorType: ObjectType[Unit, Sponsor] =
    ObjectType(
      "sponsor",
      "Sponsor",
      () => fields[Unit, Sponsor](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val EditionType: ObjectType[Unit, Edition] =
    ObjectType(
      "edition",
      "A child element of <editionstmt> for recording the version of an EAD instance.",
      () => fields[Unit, Edition](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val EditionstmtType: ObjectType[Unit, Editionstmt] =
    ObjectType(
      "editionstmt",
      "A child element of <filedesc>, used to provide information about the version of an EAD instance.",
      () => fields[Unit, Editionstmt](
        Field("editionstmtoption",
          sangria.schema.ListType(EditionStmtOptionType),
          resolve = _.value.editionstmtoption.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val PublicationstmtType: ObjectType[Unit, Publicationstmt] =
    ObjectType(
      "publicationstmt",
      "An optional child element of <filedesc> that provides information concerning the publication or distribution " +
        "of the EAD instance. ",
      () => fields[Unit, Publicationstmt](
        Field("publicationstmtoption",
          sangria.schema.ListType(PublicationStmtOptionType),
          resolve = _.value.publicationstmtoption.map(_.value)),//[scalaxb.DataRecord[PublicationstmtOption]] = Nil,)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val PublisherType: ObjectType[Unit, Publisher] =
    ObjectType(
      "publisher",
      "A child element of <publicationstmt> that identifies the institution or agency responsible for distribution " +
        "of the EAD instance.",
      () => fields[Unit, Publisher](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val AddressType: ObjectType[Unit, Address] =
    ObjectType(
      "address",
      "An element that binds together one or more <addressline> elements that provide contact information for " +
        "a repository or publisher.",
      () => fields[Unit, Address](
        Field("addressline", sangria.schema.ListType(AddresslineType), resolve = _.value.addressline),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
      )
    )

  implicit val AddresslineType: ObjectType[Unit, Addressline] =
    ObjectType(
      "addressline",
      "A generic element for recording one line of an address, whether postal or other.",
      () => fields[Unit, Addressline](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val MaintenancestatusType: ObjectType[Unit, Maintenancestatus] =
    ObjectType(
      "maintenancestatus",
        "New or Revised status based on the state of the current instance of the EAD",
      () => fields[Unit, Maintenancestatus](
           Field("mixed", sangria.schema.ListType(StringType),
             resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
          Field("id", OptionType(StringType), resolve = _.value.id),
          Field("altrender", OptionType(StringType), resolve = _.value.altrender),
          Field("audience", OptionType(StringType),
            resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
          Field("lang", OptionType(StringType), resolve = _.value.lang),
          Field("script", OptionType(StringType), resolve = _.value.script),
          Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
          Field("value", StringType,
            resolve = {ctx => Resolvers.valueResolver(ctx.value.valueAttribute)})
        )
      )

  implicit val MaintenanceagencyType: ObjectType[Unit, Maintenanceagency] =
    ObjectType(
      "maintenanceagency",
      "Information about the institution or service responsible for the creation, maintenance, " +
        "and/or dissemination of the EAD instance. ",
      () => fields[Unit, Maintenanceagency](
        Field("agencycode", OptionType(AgencycodeType), resolve = _.value.agencycode),
        Field("otheragencycode", sangria.schema.ListType(OtheragencycodeType), resolve = _.value.otheragencycode),
        Field("agencyname", sangria.schema.ListType(AgencynameType), resolve = _.value.agencyname),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("countrycode", OptionType(StringType), resolve = _.value.countrycode)
      )
    )

  implicit val AgencynameType: ObjectType[Unit, Agencyname] =
    ObjectType(
      "agencyname",
      "A required child element of <maintenanceagency> that provides the name of the institution or " +
        "service responsible for the creation, maintenance, and/or dissemination of the EAD instance.",
      () => fields[Unit, Agencyname](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  //TODO: Follow the International Standard Identifier for Libraries and Related Organizations
  //TODO: (ISIL: ISO 15511): a prefix, a dash, and an identifier to restrict the possible agency code values.
  implicit val AgencycodeType: ObjectType[Unit, Agencycode] =
    ObjectType(
      "agencycode",
      "A child element of <maintenanceagency> that provides a code for the institution or service responsible " +
        "for the creation, maintenance, and/or dissemination of the EAD instance.",
      () => fields[Unit, Agencycode](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  //TODO: The addition of an ISO 3166-1 alpha-2 country code as the prefix to a local code is recommended to ensure
  //TODO: international uniqueness.
  implicit val OtheragencycodeType: ObjectType[Unit, Otheragencycode] =
    ObjectType(
      "otheragencycode",
      "A child element of <maintenanceagency> that provides an alternative code for the institution or " +
        "service responsible for the EAD instance.",
      () => fields[Unit, Otheragencycode](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val LanguagedeclarationType: ObjectType[Unit, Languagedeclaration] =
    ObjectType(
      "languagedeclaration",
      "The language and script in which the EAD is written",
      () => fields[Unit, Languagedeclaration](
        Field("language", LanguageType, resolve = _.value.language),
        Field("scriptElement", ScriptType, resolve = _.value.scriptElement),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val LanguageType: ObjectType[Unit, Language] =
    ObjectType(
      "language",
      "An element used to indicate the language or communication system of an EAD instance or of the material " +
        "being described.",
      () => fields[Unit, Language](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("langcode", OptionType(StringType), resolve = _.value.langcode)
      )
    )

  implicit val ScriptType: ObjectType[Unit, Script] =
    ObjectType(
      "script",
      "A child element of <languagedeclaration> and <languageset> that identifies the writing script for a language " +
        "of the EAD instance or the materials being described, respectively.",
      () => fields[Unit, Script](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("label", OptionType(StringType), resolve = _.value.label),
        Field("scriptcode", OptionType(StringType), resolve = _.value.scriptcode)
      )
    )

  implicit val ConventiondeclarationType: ObjectType[Unit, Conventiondeclaration] =
    ObjectType[Unit, Conventiondeclaration](
      "conventiondeclaration",
      "An optional child element of <control>, used to bind together <citation> with optional <abbr> and " +
        "<descriptivenote> elements that identify rules or conventions applied in compiling the description",
      () => fields[Unit, Conventiondeclaration](
        Field("abbr", OptionType(AbbrType), resolve = _.value.abbr),
        Field("citation", CitationType, resolve = _.value.citation),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit lazy val RightsdeclarationType: ObjectType[Unit, Rightsdeclaration] =
    ObjectType(
      "rightsdeclaration",
      "Unsure why this is generated and not documented at: https://www.loc.gov/ead/EAD3taglib/index.html#elem-control",
      () => fields[Unit, Rightsdeclaration](
        Field("abbr", OptionType(AbbrType), resolve = _.value.abbr),
        Field("citation", CitationType, resolve = _.value.citation),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit lazy val LocaltypedeclarationType: ObjectType[Unit, Localtypedeclaration] =
    ObjectType(
      "localtypedeclaration",
      "A child element of <control> used to declare any local conventions or controlled vocabularies used in " +
        "localtype in the EAD instance. ",
      () => fields[Unit, Localtypedeclaration](
        Field("abbr", OptionType(AbbrType), resolve = _.value.abbr),
        Field("citation", CitationType, resolve = _.value.citation),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val CitationType: ObjectType[Unit, Citation] =
    ObjectType(
      "citation",
      "A required child element of <conventiondeclaration> and <localtypedeclaration> for identifying any " +
        "rules and conventions applied in the compilation of the description.",
      () => fields[Unit, Citation](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOption1Type),
          resolve = {ctx => Resolvers.mMixedBasicElementsOption1Resolver(ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("href", OptionType(StringType), resolve = _.value.href),
        Field("linkrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.linkrole)}),
        Field("arcrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.arcrole)}),
        Field("linktitle", OptionType(StringType), resolve = _.value.linktitle),
        Field("show", OptionType(StringType),
          resolve = {ctx => Resolvers.showTypeResolver(ctx.value.show)}),
        Field("actuate", OptionType(StringType),
          resolve = {ctx => Resolvers.actuateTypeResolver(ctx.value.actuate)}),
        Field("lastdatetimeverified", OptionType(StringType), resolve = _.value.lastdatetimeverified)
      )
    )


  implicit val LocalcontrolType: ObjectType[Unit, Localcontrol] =
    ObjectType(
      "localcontrol",
      "A child element of <control>, used to specify any control information necessary to accommodate local practice. ",
      () => fields[Unit, Localcontrol](
        Field("term", OptionType(TermType), resolve = _.value.term),
        Field("localcontroloption",
          OptionType(LocalControlOptionType),
          resolve = {ctx => Resolvers.localControlOptionResolver(ctx.value.localcontroloption)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val DatesingleType: ObjectType[Unit, Datesingle] =
    ObjectType(
      "datesingle",
      "An element for encoding an individual date related to the materials being described.",
      () => fields[Unit, Datesingle](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOption1Type),
          resolve = {ctx => Resolvers.mMixedBasicElementsOption1Resolver(ctx.value.mixed)}),
        Field("standarddate", OptionType(StringType), resolve = _.value.standarddate),
        Field("notbefore", OptionType(StringType), resolve = _.value.notbefore),
        Field("notafter", OptionType(StringType), resolve = _.value.notafter),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val DaterangeType: ObjectType[Unit, Daterange] =
    ObjectType(
      "daterange",
      "A wrapper element for binding together <fromdate> and <todate> in order to represent a range of dates.",
      () => fields[Unit, Daterange](
        Field("fromdate", OptionType(FromdateType), resolve = _.value.fromdate),
        Field("todate", OptionType(TodateType), resolve = _.value.todate),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val FromdateType: ObjectType[Unit, Fromdate] =
    ObjectType(
      "fromdate",
      "An optional child element of <daterange> that records the starting point in a range of dates.",
      () => fields[Unit, Fromdate](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("standarddate", OptionType(StringType), resolve = _.value.standarddate),
        Field("notbefore", OptionType(StringType), resolve = _.value.notbefore),
        Field("notafter", OptionType(StringType), resolve = _.value.notafter),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val TodateType: ObjectType[Unit, Todate] =
    ObjectType(
      "todate",
      "A child element of <daterange> that records the end point in a range of dates.",
      () => fields[Unit, Todate](
        Field("mixed",
          sangria.schema.ListType(MixedBasicElementsOptionType),
          resolve = {ctx => Resolvers.mMixedBasicElementsOptionResolver(ctx.value.mixed)}),
        Field("standarddate", OptionType(StringType), resolve = _.value.standarddate),
        Field("notbefore", OptionType(StringType), resolve = _.value.notbefore),
        Field("notafter", OptionType(StringType), resolve = _.value.notafter),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val TermType: ObjectType[Unit, Term] =
    ObjectType(
      "term",
      "A child element of <localcontrol> used to specify a descriptive term in accordance with local rules.",
      () => fields[Unit, Term](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("transliteration", OptionType(StringType), resolve = _.value.transliteration),
        Field("lastdatetimeverified", OptionType(StringType), resolve = _.value.lastdatetimeverified),
        Field("source", OptionType(StringType), resolve = _.value.source),
        Field("rules", OptionType(StringType), resolve = _.value.rules),
        Field("identifier", OptionType(StringType), resolve = _.value.identifier)
      )
    )

  implicit val MaintenancehistoryType: ObjectType[Unit, Maintenancehistory] =
    ObjectType(
      "maintenancehistory",
      "A required child element of <control> that captures the history of the EAD instance. ",
      () => fields[Unit, Maintenancehistory](
        Field("maintenanceevent", sangria.schema.ListType(MaintenanceeventType), resolve = _.value.maintenanceevent),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
  )

  implicit val MaintenanceeventType: ObjectType[Unit, Maintenanceevent] =
    ObjectType(
      "maintenanceevent",
      "A required child element of <maintenancehistory> used to record information about maintenance activities in " +
        "the history of the EAD instance.",
      () => fields[Unit, Maintenanceevent](
        Field("eventtype", EventtypeType, resolve = _.value.eventtype),
        Field("eventdatetime", EventdatetimeType, resolve = _.value.eventdatetime),
        Field("agenttype", AgenttypeType, resolve = _.value.agenttype),
        Field("agent", AgentType, resolve = _.value.agent),
        Field("eventdescription", sangria.schema.ListType(EventdescriptionType),
          resolve = _.value.eventdescription),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val EventdescriptionType: ObjectType[Unit, Eventdescription] =
    ObjectType(
      "eventdescription",
      "An optional child of <maintenanceevent>, used to provide a description of the maintenance activity.",
      () => fields[Unit, Eventdescription](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype)
      )
    )

  implicit val AgentType: ObjectType[Unit, Agent] =
    ObjectType(
      "agent",
      "A required child element of <maintenanceevent> that provides the name of a person, institution, or system " +
        "responsible for the creation, modification, or deletion of an EAD instance.",
      () => fields[Unit, Agent](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val AgenttypeType: ObjectType[Unit, Agenttype] =
    ObjectType(
      "agenttype",
      "A required child element of <maintenanceevent> that indicates the type of agent responsible for the " +
        "creation, modification, or deletion of an EAD instance.",
      () => fields[Unit, Agenttype](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("value", StringType, resolve = {ctx => Resolvers.valueType3Resolver(ctx.value.valueAttribute)})
      )
    )

  implicit val EventtypeType: ObjectType[Unit, Eventtype] =
    ObjectType(
      "eventtype",
      "A required child element of <maintenanceevent> that provides a controlled list of values for recording the " +
        "type of maintenance activity.",
      () => fields[Unit, Eventtype](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("value", StringType, resolve = {ctx => Resolvers.valueType2Resolver(ctx.value.valueAttribute)})
      )
    )

  implicit val EventdatetimeType: ObjectType[Unit, Eventdatetime] =
    ObjectType(
      "eventdatetime",
      "A required child element of <maintenanceevent> that records the date and time of a specific maintenance " +
        "action for an EAD instance.",
      () => fields[Unit, Eventdatetime](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("standarddatetime", OptionType(StringType), resolve = _.value.standarddatetime)
      )
    )

  implicit lazy val SourcesType: ObjectType[Unit, Sources] =
    ObjectType(
      "sources",
      "An optional child element of <control> that groups one or more <source>s of evidence used in describing " +
        "the archival material. ",
      () => fields[Unit, Sources](
        Field("source", sangria.schema.ListType(SourceType), resolve = _.value.source),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("localtype", OptionType(StringType), resolve = _.value.localtype),
        Field("base", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.base)})
      )
    )

  implicit val SourceType: ObjectType[Unit, Source] =
    ObjectType(
      "source",
      "A child element of <sources> used to identify a particular source of evidence used in describing the archival material.",
      () => fields[Unit, Source](
        Field("sourceentry",
          sangria.schema.ListType(SourceEntryType),
          resolve = _.value.sourceentry),
        Field("objectxmlwrap", OptionType(ObjectXmlWrapType), resolve = _.value.objectxmlwrap),
        Field("descriptivenote", OptionType(DescriptiveNoteType), resolve = _.value.descriptivenote),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("lastdatetimeverified", OptionType(StringType), resolve = _.value.lastdatetimeverified),
        Field("href", OptionType(StringType), resolve = _.value.href),
        Field("linkrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.linkrole)}),
        Field("arcrole", OptionType(StringType),
          resolve = {ctx => Resolvers.uriResolver(ctx.value.arcrole)}),
        Field("linktitle", OptionType(StringType), resolve = _.value.linktitle),
        Field("show", OptionType(StringType),
          resolve = {ctx => Resolvers.showTypeResolver(ctx.value.show)}),
        Field("actuate", OptionType(StringType),
          resolve = {ctx => Resolvers.actuateTypeResolver(ctx.value.actuate)})
      )
    )

  implicit val SourceEntryType: ObjectType[Unit, Sourceentry] =
    ObjectType(
      "sourceentry",
      "A child element within <source> that identifies a specific source used in creating the archival description.",
      () => fields[Unit, Sourceentry](
        Field("mixed", sangria.schema.ListType(StringType),
          resolve = {ctx => Resolvers.textDataRecordResolver[String](ctx.value.mixed)}),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog),
        Field("transliteration", OptionType(StringType), resolve = _.value.transliteration)
      )
    )

  implicit val ObjectXmlWrapType: ObjectType[Unit, Objectxmlwrap] =
    ObjectType(
      "objectxmlwrap",
      "A sublement of <relation> and <source> that allows for the inclusion of an XML element from any XML namespace " +
        "other than EAD.",
      () => fields[Unit, Objectxmlwrap](
        //TODO: Requires more thought
        // Field("any": scalaxb.DataRecord[Any],
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script)
  //extends Eu46anynamable
      )
    )

  implicit val DescriptiveNoteType: ObjectType[Unit, Descriptivenote] =
    ObjectType(
      "descriptivenote",
      "An element used to provide general descriptive information related to its parent element.",
      () => fields[Unit, Descriptivenote](
        Field("p", sangria.schema.ListType(PType), resolve = _.value.p),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType),
          resolve = ctx => Resolvers.audienceResolver(ctx.value.audience)),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val DscType: ObjectType[Unit, Dsc] =
    ObjectType(
      "dsc",
      "A wrapper element that bundles information about the hierarchical groupings of the materials being described.",
      ()=> fields[Unit, Dsc](
        Field("dscsequence1", DscSequence1Type, resolve = _.value.dscsequence1),
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("mu46cOrC01Option3", sangria.schema.ListType(COrC01Type),
          resolve = _.value.mu46cOrC01Option3.map(_.value)),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = {ctx => Resolvers.audienceResolver(ctx.value.audience)}),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("dsctype", OptionType(StringType), resolve = _.value.dsctype.toString),
        Field("otherdsctype", OptionType(StringType), resolve = _.value.otherdsctype),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val DscSequence1Type: ObjectType[Unit, DscSequence1] =
    ObjectType(
      "dscsequence1",
      "head and m.blocks.option",
      () => fields[Unit, DscSequence1](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("blocksOption2", sangria.schema.ListType(BlocksOptionType),
          resolve = _.value.mu46blocksOption2.map(p => p.value))
      )
    )

  implicit val CType: ObjectType[Unit, C] =
    ObjectType(
      "c",
      "An element that designates a subordinate part of the materials being described.",
      () => fields[Unit, C](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", OptionType(DidType), resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("csequence1", sangria.schema.ListType(CSequence1Type), resolve = _.value.csequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C01Type: ObjectType[Unit, C01] =
    ObjectType(
      "c01",
      "An element that designates the top or first-level subordinate part of the materials.",
      () => fields[Unit, C01](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c01sequence1", sangria.schema.ListType(C01Sequence1Type), resolve = _.value.c01sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val CSequence1Type: ObjectType[Unit, CSequence1] =
    ObjectType(
      "csequence1",
      "Thead and c",
      () => fields[Unit, CSequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c", sangria.schema.ListType(CType), resolve = _.value.c)
      )
    )

  implicit val C01Sequence1Type: ObjectType[Unit, C01Sequence1] =
    ObjectType(
      "c01sequence",
      "thead and C02 sequence",
      () => fields[Unit, C01Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c02", sangria.schema.ListType(C02Type), resolve = _.value.c02)
      )
    )

  implicit val C02Type: ObjectType[Unit, C02] =
    ObjectType(
      "c02",
      "An element that designates the top or second-level subordinate part of the materials.",
      () => fields[Unit, C02](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c02sequence1", sangria.schema.ListType(C02Sequence1Type), resolve = _.value.c02sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C02Sequence1Type: ObjectType[Unit, C02Sequence1] =
    ObjectType(
      "c02sequence",
      "thead and C03 sequence",
      () => fields[Unit, C02Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c03", sangria.schema.ListType(C03Type), resolve = _.value.c03)
      )
    )

  implicit val C03Type: ObjectType[Unit, C03] =
    ObjectType(
      "c03",
      "An element that designates the top or third-level subordinate part of the materials.",
      () => fields[Unit, C03](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c03sequence1", sangria.schema.ListType(C03Sequence1Type), resolve = _.value.c03sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C03Sequence1Type: ObjectType[Unit, C03Sequence1] =
    ObjectType(
      "c03sequence",
      "thead and C04 sequence",
      () => fields[Unit, C03Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c04", sangria.schema.ListType(C04Type), resolve = _.value.c04)
      )
    )

  implicit val C04Type: ObjectType[Unit, C04] =
    ObjectType(
      "c04",
      "An element that designates the top or fourth-level subordinate part of the materials.",
      () => fields[Unit, C04](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c04sequence1", sangria.schema.ListType(C04Sequence1Type), resolve = _.value.c04sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C04Sequence1Type: ObjectType[Unit, C04Sequence1] =
    ObjectType(
      "c04sequence",
      "thead and C05 sequence",
      () => fields[Unit, C04Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c05", sangria.schema.ListType(C05Type), resolve = _.value.c05)
      )
    )

  implicit val C05Type: ObjectType[Unit, C05] =
    ObjectType(
      "c05",
      "An element that designates the top or fifth-level subordinate part of the materials.",
      () => fields[Unit, C05](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c05sequence1", sangria.schema.ListType(C05Sequence1Type), resolve = _.value.c05sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C05Sequence1Type: ObjectType[Unit, C05Sequence1] =
    ObjectType(
      "c05sequence",
      "thead and C06 sequence",
      () => fields[Unit, C05Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c06", sangria.schema.ListType(C06Type), resolve = _.value.c06)
      )
    )

  implicit val C06Type: ObjectType[Unit, C06] =
    ObjectType(
      "c06",
      "An element that designates the top or sixth-level subordinate part of the materials.",
      () => fields[Unit, C06](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c06sequence1", sangria.schema.ListType(C06Sequence1Type), resolve = _.value.c06sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C06Sequence1Type: ObjectType[Unit, C06Sequence1] =
    ObjectType(
      "c06sequence",
      "thead and C07 sequence",
      () => fields[Unit, C06Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c07", sangria.schema.ListType(C07Type), resolve = _.value.c07)
      )
    )

  implicit val C07Type: ObjectType[Unit, C07] =
    ObjectType(
      "c07",
      "An element that designates the top or seventh-level subordinate part of the materials.",
      () => fields[Unit, C07](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c07sequence1", sangria.schema.ListType(C07Sequence1Type), resolve = _.value.c07sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C07Sequence1Type: ObjectType[Unit, C07Sequence1] =
    ObjectType(
      "c07sequence",
      "thead and C08 sequence",
      () => fields[Unit, C07Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c08", sangria.schema.ListType(C08Type), resolve = _.value.c08)
      )
    )

  implicit val C08Type: ObjectType[Unit, C08] =
    ObjectType(
      "c08",
      "An element that designates the top or eighth-level subordinate part of the materials.",
      () => fields[Unit, C08](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c08sequence1", sangria.schema.ListType(C08Sequence1Type), resolve = _.value.c08sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C08Sequence1Type: ObjectType[Unit, C08Sequence1] =
    ObjectType(
      "c08sequence",
      "thead and C09 sequence",
      () => fields[Unit, C08Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c09", sangria.schema.ListType(C09Type), resolve = _.value.c09)
      )
    )

  implicit val C09Type: ObjectType[Unit, C09] =
    ObjectType(
      "c09",
      "An element that designates the top or ninth-level subordinate part of the materials.",
      () => fields[Unit, C09](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c09sequence1", sangria.schema.ListType(C09Sequence1Type), resolve = _.value.c09sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C09Sequence1Type: ObjectType[Unit, C09Sequence1] =
    ObjectType(
      "c09sequence",
      "thead and C10 sequence",
      () => fields[Unit, C09Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c10", sangria.schema.ListType(C10Type), resolve = _.value.c10)
      )
    )

  implicit val C10Type: ObjectType[Unit, C10] =
    ObjectType(
      "c10",
      "An element that designates the top or tenth-level subordinate part of the materials.",
      () => fields[Unit, C10](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c10sequence1", sangria.schema.ListType(C10Sequence1Type), resolve = _.value.c10sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C10Sequence1Type: ObjectType[Unit, C10Sequence1] =
    ObjectType(
      "c10sequence",
      "thead and C11 sequence",
      () => fields[Unit, C10Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead),
        Field("c11", sangria.schema.ListType(C11Type), resolve = _.value.c11)
      )
    )

  implicit val C11Type: ObjectType[Unit, C11] =
    ObjectType(
      "c11",
      "An element that designates the top or eleventh-level subordinate part of the materials.",
      () => fields[Unit, C11](
        Field("head", OptionType(HeadType), resolve = _.value.head),
        Field("did", DidType, resolve = _.value.did),
        Field("descBaseOption3", sangria.schema.ListType(DesBaseOptionType),
          resolve = _.value.mu46descu46baseOption3.map(p => p.value)),
        Field("c11sequence1", sangria.schema.ListType(C11Sequence1Type), resolve = _.value.c11sequence1),
        Field("id", OptionType(StringType), resolve = _.value.id),
        Field("altrender", OptionType(StringType), resolve = _.value.altrender),
        Field("audience", OptionType(StringType), resolve = _.value.audience.toString),
        Field("lang", OptionType(StringType), resolve = _.value.lang),
        Field("script", OptionType(StringType), resolve = _.value.script),
        Field("base", OptionType(StringType), resolve = {ctx => Resolvers.uriResolver(ctx.value.base)}),
        Field("level", OptionType(StringType), resolve = _.value.level.toString),
        Field("otherlevel", OptionType(StringType), resolve = _.value.otherlevel),
        Field("encodinganalog", OptionType(StringType), resolve = _.value.encodinganalog)
      )
    )

  implicit val C11Sequence1Type: ObjectType[Unit, C11Sequence1] =
    ObjectType(
      "c11sequence",
      "thead and C12 sequence",
      () => fields[Unit, C11Sequence1](
        Field("thead", OptionType(TheadType), resolve = _.value.thead)
      )
    )

  val schema = Schema(QueryType)//, Some(MutationType))//,
//    additionalTypes = ItemType :: FondType :: Nil)

}